<script lang="ts" setup>
import { get, post, Message, loadFile } from '@/utils'
import draggable from 'vuedraggable'

type Emits = {
  success: [img: string]
  'update:list': [list: string[]]
  remove: [index: number]
  fail: []
  file: any
  'update:value': [string]
}
const props = withDefaults(
  defineProps<{
    separator?: string //切割标识
    list: any[] | string //文件列表|需要根据标识切割的字符串
    preview?: boolean //开启图片预览
    accept?: string //上传文件类型
    disabled?: boolean //禁用
    multiple?: boolean //多文件上传
    tip?: string
    value?: string
    limit?: number //上传数量
    showRemoveBtn?: boolean //显示删除按钮
    showBtn?: boolean //是否显示上传按钮
    listType?: 'text' | 'picture' | 'picture-card' //图片列表类型
    api?: string
    fileName?: string
    notUpload?: boolean
  }>(),
  {
    notUpload: false,
    preview: true,
    disabled: false,
    multiple: false,
    accept: '.jpg,.JPG,.JPEG,.jpeg,.png,.PNG',
    limit: 0,
    showRemoveBtn: true,
    showBtn: true,
    separator: ',',
    listType: 'picture-card',
    api: '/sys-seller/uploads',
  }
)

const valStr = ref('')
const emit = defineEmits<Emits>()
const fileList = ref<any[]>([])
/**上传图片 */
const customRequest = option => {
  const { onProgress, onError, onSuccess, fileItem, name } = option
  const formData = new FormData()
  emit('file', fileItem.file)
  if (props.notUpload) {
    onProgress(100)
    onSuccess()
    return {
      abort() {},
    }
  }
  formData.append('file', fileItem.file)
  // formData.append('directoryName', 'admin')
  post(
    {
      url: '/server-resource/oss/endpoint/put/file',
      data: formData,
      headers: {
        'Content-Type': 'multipart/form-data; boundary=----WebKitFormBoundaryMBKIj1uGXeRNivgf',
      },
    },
    ({ data }) => {
      onProgress(100)
      console.log(data)
      const list = valStr.value.split(',').filter(Boolean)
      list.push(data.link)
      valStr.value = list.join(',')
      onSuccess()
      emit('update:value', valStr.value)
      emit('success', data.data)
    },
    ({ msg }) => {
      onError(msg)
      Message.error(msg || '上传失败')
    }
  )

  return {
    abort() {},
  }
}
/**删除 */
const onRemove = (fileItem): any => {
  return new Promise((resolve, reject) => {
    const _index = fileList.value.findIndex(f => f.url == fileItem.url)
    if (_index != -1) {
      emit('remove', _index)
      const list = valStr.value.split(',').filter(Boolean)
      list.splice(_index, 1)
      valStr.value = list.join(',')
      fileList.value.splice(_index, 1)
      emit('update:value', valStr.value)
      resolve(true)
    } else reject(false)
  })
}
const initImg = img => {
  console.log('initImg')
  fileList.value = []
  if (img && typeof img === 'string') {
    img
      .split(props.separator)
      .filter(Boolean)
      .forEach((item, i) => {
        fileList.value.push({
          url: item,
          name: (props.fileName ?? '') + (i + 1),
        })
      })
    valStr.value = props.list as string
  } else {
    if (!img?.length) return
    ;(img as any[]).map((v, i) => {
      fileList.value.push({
        url: v,
        name: (props.fileName ?? '') + (i + 1),
      })
    })
  }
}
/**监听重置fileList */
watch(
  () => props.list,
  n => initImg(n)
)
onMounted(() => {
  initImg(props.list)
})
/**
 * 拖拽变更排序
 */
const onMove = () => {
  let str: string[] = []
  fileList.value.map((item, i) => {
    str.push(item.url)
  })
  valStr.value = str.join(',')
  emit('update:value', valStr.value)
}
</script>
<template>
  <div class="upload-box flex">
    <draggable class="imgs flex" :list="fileList" @end="onMove" animation="300" ghost-class="ghost" :force-fallback="true" :group="{ name: 'list', pull: 'clone', put: false }" itemKey="name">
      <template #item="{ element }">
        <div class="img mr5">
          <div class="mark flex">
            <icon-delete @click="onRemove(element)" style="margin: auto; color: white" color="white" size="20" />
          </div>
          <a-image :src="element.url" :width="80" :height="80"> </a-image>
        </div>
      </template>
    </draggable>

    <a-upload
      :list-type="props.listType"
      action="/"
      :show-file-list="false"
      v-model:file-list="fileList"
      :limit="props.limit"
      :image-preview="props.preview"
      :disabled="props.disabled"
      :multiple="props.multiple"
      :show-remove-button="props.showRemoveBtn"
      :tip="props.tip"
      :show-upload-button="props.showBtn"
      :accept="props.accept"
      :custom-request="customRequest"
      @before-remove="fileItem => onRemove(fileItem)"
    />
  </div>
</template>
<style lang="less" scoped>
.img {
  width: 80px;
  height: 80px;
  cursor: pointer;
  position: relative;
  &:hover {
    .mark {
      display: flex;
    }
  }
  .mark {
    position: absolute;
    top: 0;
    left: 0;
    width: 80px;
    height: 80px;
    z-index: 1;
    display: none;
    background: rgba(0, 0, 0, 0.5);
  }
  img {
    width: 100%;
    height: 100%;
  }
}
</style>
